package com.uduemc.biso.node.module.service.impl;

import java.util.Date;
import java.util.List;
import java.util.Optional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.uduemc.biso.node.core.entities.SInformationTitle;
import com.uduemc.biso.node.core.entities.custom.information.InformationTitleFileConf;
import com.uduemc.biso.node.core.entities.custom.information.InformationTitleImageConf;
import com.uduemc.biso.node.module.mapper.SInformationTitleMapper;
import com.uduemc.biso.node.module.service.SInformationTitleService;

import cn.hutool.core.collection.CollUtil;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.entity.Example.Criteria;

@Service
public class SInformationTitleServiceImpl implements SInformationTitleService {

	public static final String ORDER_BY_ASC = "`s_information_title`.`order_num` ASC, `s_information_title`.`id` ASC";

	public static final String ORDER_BY_DESC = "`s_information_title`.`order_num` DESC, `s_information_title`.`id` DESC";

	@Autowired
	private SInformationTitleMapper sInformationTitleMapper;

	@Autowired
	private ObjectMapper objectMapper;

	@Override
	public SInformationTitle insertAndUpdateCreateAt(SInformationTitle sInformationTitle) {
		sInformationTitleMapper.insert(sInformationTitle);
		SInformationTitle findOne = findOne(sInformationTitle.getId());
		Date createAt = sInformationTitle.getCreateAt();
		if (createAt != null) {
			sInformationTitleMapper.updateCreateAt(findOne.getId(), createAt, SInformationTitle.class);
		}
		return findOne;
	}

	@Override
	public SInformationTitle insert(SInformationTitle sInformationTitle) {
		sInformationTitleMapper.insert(sInformationTitle);
		return findOne(sInformationTitle.getId());
	}

	@Override
	public SInformationTitle insertSelective(SInformationTitle sInformationTitle) {
		sInformationTitleMapper.insertSelective(sInformationTitle);
		return findOne(sInformationTitle.getId());
	}

	@Override
	public SInformationTitle updateByPrimaryKey(SInformationTitle sInformationTitle) {
		sInformationTitleMapper.updateByPrimaryKey(sInformationTitle);
		return findOne(sInformationTitle.getId());
	}

	@Override
	public SInformationTitle updateByPrimaryKeySelective(SInformationTitle sInformationTitle) {
		sInformationTitleMapper.updateByPrimaryKeySelective(sInformationTitle);
		return findOne(sInformationTitle.getId());
	}

	@Override
	public SInformationTitle findOne(long id) {
		return sInformationTitleMapper.selectByPrimaryKey(id);
	}

	@Override
	public SInformationTitle findByHostSiteIdAndId(long id, long hostId, long siteId) {
		Example example = new Example(SInformationTitle.class);

		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("id", id);
		criteria.andEqualTo("hostId", hostId);
		criteria.andEqualTo("siteId", siteId);

		return sInformationTitleMapper.selectOneByExample(example);
	}

	@Override
	public SInformationTitle findByHostSiteSystemIdAndId(long id, long hostId, long siteId, long systemId) {
		Example example = new Example(SInformationTitle.class);

		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("id", id);
		criteria.andEqualTo("hostId", hostId);
		criteria.andEqualTo("siteId", siteId);
		criteria.andEqualTo("systemId", systemId);

		return sInformationTitleMapper.selectOneByExample(example);
	}

	@Override
	public SInformationTitle findMaxOrderNumInfoByHostSiteSystemId(long hostId, long siteId, long systemId) {
		Example example = new Example(SInformationTitle.class);

		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("hostId", hostId);
		criteria.andEqualTo("siteId", siteId);
		criteria.andEqualTo("systemId", systemId);

		example.setOrderByClause(ORDER_BY_DESC);
		PageHelper.startPage(1, 1);

		return sInformationTitleMapper.selectOneByExample(example);
	}

	@Override
	public List<SInformationTitle> findInfosByHostSiteId(long hostId, long siteId) {
		Example example = new Example(SInformationTitle.class);

		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("hostId", hostId);
		criteria.andEqualTo("siteId", siteId);

		example.setOrderByClause(ORDER_BY_ASC);

		return sInformationTitleMapper.selectByExample(example);
	}

	@Override
	public List<SInformationTitle> findInfosByHostSiteSystemId(long hostId, long siteId, long systemId) {
		Example example = new Example(SInformationTitle.class);

		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("hostId", hostId);
		criteria.andEqualTo("siteId", siteId);
		criteria.andEqualTo("systemId", systemId);

		example.setOrderByClause(ORDER_BY_ASC);

		return sInformationTitleMapper.selectByExample(example);
	}

	@Override
	public List<SInformationTitle> findOkInfosByHostSiteSystemId(long hostId, long siteId, long systemId) {
		Example example = new Example(SInformationTitle.class);

		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("hostId", hostId);
		criteria.andEqualTo("siteId", siteId);
		criteria.andEqualTo("systemId", systemId);
		criteria.andEqualTo("status", (short) 1);

		example.setOrderByClause(ORDER_BY_ASC);

		return sInformationTitleMapper.selectByExample(example);
	}

	@Override
	public List<SInformationTitle> findInfosByHostSiteIdAndIds(List<Long> ids, long hostId, long siteId) {
		Example example = new Example(SInformationTitle.class);

		Criteria criteria = example.createCriteria();
		criteria.andIn("id", ids);
		criteria.andEqualTo("hostId", hostId);
		criteria.andEqualTo("siteId", siteId);

		example.setOrderByClause(ORDER_BY_ASC);

		return sInformationTitleMapper.selectByExample(example);
	}

	@Override
	public List<SInformationTitle> findInfosByHostSiteSystemIdAndIds(List<Long> ids, long hostId, long siteId, long systemId) {
		Example example = new Example(SInformationTitle.class);

		Criteria criteria = example.createCriteria();
		criteria.andIn("id", ids);
		criteria.andEqualTo("hostId", hostId);
		criteria.andEqualTo("siteId", siteId);
		criteria.andEqualTo("systemId", systemId);

		example.setOrderByClause(ORDER_BY_ASC);

		return sInformationTitleMapper.selectByExample(example);
	}

	@Override
	public int deleteByHostSiteId(long hostId, long siteId) {
		Example example = new Example(SInformationTitle.class);

		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("hostId", hostId);
		criteria.andEqualTo("siteId", siteId);

		return sInformationTitleMapper.deleteByExample(example);
	}

	@Override
	public int deleteByHostSiteSystemId(long hostId, long siteId, long systemId) {
		Example example = new Example(SInformationTitle.class);

		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("hostId", hostId);
		criteria.andEqualTo("siteId", siteId);
		criteria.andEqualTo("systemId", systemId);

		return sInformationTitleMapper.deleteByExample(example);
	}

	@Override
	public SInformationTitle deleteByHostSiteIdAndId(long id, long hostId, long siteId) {
		SInformationTitle sInformationTitle = findByHostSiteIdAndId(id, hostId, siteId);
		if (sInformationTitle == null) {
			return null;
		}

		sInformationTitleMapper.deleteByPrimaryKey(id);

		return sInformationTitle;
	}

	@Override
	public PageInfo<SInformationTitle> findPageInfoAll(long hostId, long siteId, int pageNum, int pageSize) {
		Example example = new Example(SInformationTitle.class);
		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("hostId", hostId);
		criteria.andEqualTo("siteId", siteId);
		example.setOrderByClause(ORDER_BY_ASC);
		PageHelper.startPage(pageNum, pageSize);
		List<SInformationTitle> list = sInformationTitleMapper.selectByExample(example);
		PageInfo<SInformationTitle> result = new PageInfo<>(list);
		return result;
	}

	@Override
	public PageInfo<SInformationTitle> findPageInfoAll(long hostId, long siteId, long systemId, int pageNum, int pageSize) {
		Example example = new Example(SInformationTitle.class);
		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("hostId", hostId);
		criteria.andEqualTo("siteId", siteId);
		criteria.andEqualTo("systemId", systemId);
		example.setOrderByClause(ORDER_BY_ASC);
		PageHelper.startPage(pageNum, pageSize);
		List<SInformationTitle> list = sInformationTitleMapper.selectByExample(example);
		PageInfo<SInformationTitle> result = new PageInfo<>(list);
		return result;
	}

	@Override
	@Transactional
	public boolean initSystemData(long hostId, long siteId, long systemId) {
		SInformationTitle defaultSInformationTitle = new SInformationTitle();
		SInformationTitle imageSInformationTitle = new SInformationTitle();
		SInformationTitle fileSInformationTitle = new SInformationTitle();

		defaultSInformationTitle.setHostId(hostId).setSiteId(siteId).setSystemId(systemId);
		imageSInformationTitle.setHostId(hostId).setSiteId(siteId).setSystemId(systemId);
		fileSInformationTitle.setHostId(hostId).setSiteId(siteId).setSystemId(systemId);

		defaultSInformationTitle.setType((short) 1);
		imageSInformationTitle.setType((short) 2);
		fileSInformationTitle.setType((short) 3);

		defaultSInformationTitle.setTitle("默认信息项");
		imageSInformationTitle.setTitle("图片");
		fileSInformationTitle.setTitle("文件");

		defaultSInformationTitle.setSiteSearch((short) 0).setSiteRequired((short) 0).setStatus((short) 1).setProportion("-1").setPlaceholder("").setOrderNum(1);
		imageSInformationTitle.setSiteSearch((short) 0).setSiteRequired((short) 0).setStatus((short) 0).setProportion("-1").setPlaceholder("").setOrderNum(2);
		fileSInformationTitle.setSiteSearch((short) 0).setSiteRequired((short) 0).setStatus((short) 0).setProportion("-1").setPlaceholder("").setOrderNum(3);

		// 自定义的配置项
		defaultSInformationTitle.setConf("");
		// 图片的默认配置项
		String imageConf = "";
		String fileConf = "";
		try {
			imageConf = objectMapper.writeValueAsString(new InformationTitleImageConf());
			fileConf = objectMapper.writeValueAsString(new InformationTitleFileConf());
		} catch (JsonProcessingException e) {
		}
		imageSInformationTitle.setConf(imageConf);
		// 文件的默认配置项
		fileSInformationTitle.setConf(fileConf);

		SInformationTitle insert = insert(defaultSInformationTitle);
		if (insert == null) {
			throw new RuntimeException("写入 defaultSInformationTitle 失败！defaultSInformationTitle：" + defaultSInformationTitle);
		}
		insert = insert(imageSInformationTitle);
		if (insert == null) {
			throw new RuntimeException("写入 imageSInformationTitle 失败！imageSInformationTitle：" + imageSInformationTitle);
		}
		insert = insert(fileSInformationTitle);
		if (insert == null) {
			throw new RuntimeException("写入 fileSInformationTitle 失败！fileSInformationTitle：" + fileSInformationTitle);
		}

		return true;
	}

	@Override
	@Transactional
	public boolean resetOrdernum(List<Long> ids, long hostId, long siteId, long systemId) {
		if (CollUtil.isEmpty(ids)) {
			return false;
		}
		List<SInformationTitle> listSInformationTitle = findInfosByHostSiteSystemIdAndIds(ids, hostId, siteId, systemId);
		if (CollUtil.isEmpty(listSInformationTitle)) {
			return false;
		}
		if (CollUtil.size(listSInformationTitle) != CollUtil.size(ids)) {
			return false;
		}
		for (int i = 1; i <= ids.size(); i++) {
			Long id = ids.get(i - 1);

			Optional<SInformationTitle> findFirst = listSInformationTitle.stream().filter(item -> {
				return item.getId().longValue() == id.longValue();
			}).findFirst();
			if (!findFirst.isPresent()) {
				throw new RuntimeException("未能找到 id：" + id + " 的数据，ids：" + ids + "，listSInformationTitle：" + listSInformationTitle);
			}
			SInformationTitle sInformationTitle = findFirst.get();
			sInformationTitle.setOrderNum(i);
			updateByPrimaryKey(sInformationTitle);
		}
		return true;
	}

	@Override
	public int totalByHostSiteId(long hostId, long siteId) {
		Example example = new Example(SInformationTitle.class);

		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("hostId", hostId);
		criteria.andEqualTo("siteId", siteId);

		return sInformationTitleMapper.selectCountByExample(example);
	}

	@Override
	public SInformationTitle insertAfterById(SInformationTitle sInformationTitle, long afterId) {
		if (sInformationTitle == null) {
			return null;
		}
		Long hostId = sInformationTitle.getHostId();
		Long siteId = sInformationTitle.getSiteId();
		Long systemId = sInformationTitle.getSystemId();

		if (hostId == null || siteId == null || systemId == null) {
			return null;
		}

		if (afterId > 0) {
			if (findByHostSiteIdAndId(afterId, hostId, siteId) == null) {
				afterId = -1;
			}
		}

		if (afterId == 0) {
			afterId = -1;
		}

		if (afterId == -1L) {
			SInformationTitle findMaxOrderNumInfoByHostSiteId = findMaxOrderNumInfoByHostSiteSystemId(hostId, siteId, systemId);
			if (findMaxOrderNumInfoByHostSiteId == null || findMaxOrderNumInfoByHostSiteId.getOrderNum() == null) {
				sInformationTitle.setOrderNum(1);
			} else {
				// 获取到最大的 orderNum
				Integer orderNum = findMaxOrderNumInfoByHostSiteId.getOrderNum();
				sInformationTitle.setOrderNum(++orderNum);
			}
			return insert(sInformationTitle);
		} else if (afterId == -2L) {
			int orderNum = 1;
			sInformationTitle.setOrderNum(orderNum++);
			SInformationTitle insert = insert(sInformationTitle);
			List<SInformationTitle> listSInformationTitle = findInfosByHostSiteId(hostId, siteId);
			if (CollUtil.isNotEmpty(listSInformationTitle)) {
				for (SInformationTitle item : listSInformationTitle) {
					item.setOrderNum(orderNum++);
					updateByPrimaryKey(item);
				}
			}
			return insert;
		} else if (afterId > 0) {
			List<SInformationTitle> listSInformationTitle = findInfosByHostSiteId(hostId, siteId);
			SInformationTitle insert = null;
			if (CollUtil.isNotEmpty(listSInformationTitle)) {
				int orderNum = 1;
				for (SInformationTitle item : listSInformationTitle) {
					Integer on = item.getOrderNum();
					if (on == null || on.intValue() != orderNum) {
						item.setOrderNum(orderNum);
						updateByPrimaryKey(item);
					}

					if (item.getId().longValue() == afterId) {
						sInformationTitle.setOrderNum(++orderNum);
						insert = insert(sInformationTitle);
					}
					orderNum++;
				}
			}
			return insert;
		}
		return null;
	}

	@Override
	public int totalByHostSiteSystemId(long hostId, long siteId, long systemId) {
		Example example = new Example(SInformationTitle.class);

		Criteria criteria = example.createCriteria();
		criteria.andEqualTo("hostId", hostId);
		criteria.andEqualTo("siteId", siteId);
		criteria.andEqualTo("systemId", systemId);

		return sInformationTitleMapper.selectCountByExample(example);
	}

}
